package chatty.util.api; import chatty.Chatty; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; /** * * @author tduva */ public class EmoticonManager extends CachedManager { private static final Logger LOGGER = Logger.getLogger(EmoticonManager.class.getName()); /** * How long the Emoticons can be cached in a file after they are updated * from the API. */ public static final int CACHED_EMOTICONS_EXPIRE_AFTER = 60*60*24; private static final String FILE = Chatty.getCacheDirectory()+"emoticon_images"; private final TwitchApiResultListener listener; public EmoticonManager(TwitchApiResultListener listener) { super(FILE, CACHED_EMOTICONS_EXPIRE_AFTER, "Emoticons"); this.listener = listener; } @Override protected boolean handleData(String data) { Set<Emoticon> result = parseEmoticons(data); if (result == null || result.isEmpty()) { return false; } listener.receivedEmoticons(result); return true; } /** * Parses the list of emoticons from the Twitch API. * * @param json * @return */ private Set<Emoticon> parseEmoticons(String json) { Set<Emoticon> result = new HashSet<>(); if (json == null) { return null; } JSONParser parser = new JSONParser(); int errors = 0; try { JSONObject root = (JSONObject)parser.parse(json); JSONArray emoticons = (JSONArray)root.get("emoticons"); for (Object obj : emoticons) { if (obj instanceof JSONObject) { JSONObject emote_json = (JSONObject)obj; Emoticon emote = parseEmoticon(emote_json); if (emote == null) { if (errors < 10) { LOGGER.warning("Error loading emote: "+emote_json); } errors++; } else { result.add(emote); } } } if (errors > 0) { LOGGER.warning(errors+" emotes couldn't be loaded"); } if (errors > 100) { return null; } return result; } catch (ParseException | NullPointerException | ClassCastException ex) { LOGGER.warning("Error parsing emoticons: "+ex); return null; } } /** * Parses an Emoticon from the given JSONObject. * * @param emote The JSONObject containing the emoticon data * @return The Emoticon object or null if an error occured */ private Emoticon parseEmoticon(JSONObject emote) { try { String code = (String)emote.get("code"); int id = ((Number)emote.get("id")).intValue(); String url = Emoticon.getTwitchEmoteUrlById(id, 1); Emoticon.Builder b = new Emoticon.Builder(Emoticon.Type.TWITCH, code, url); if (emote.get("emoticon_set") != null) { int emoteSet = ((Number)emote.get("emoticon_set")).intValue(); b.setEmoteset(emoteSet); } b.setNumericId(id); return b.build(); } catch (NullPointerException | ClassCastException ex) { return null; } } }